//Original source: ResXFileCodeGeneratorEx
//http://www.codeproject.com/KB/dotnet/ResXFileCodeGeneratorEx.aspx
//Copyright 2006-2008 Dmytro Kryvko

using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.IO;
using System.Web.Hosting;
using System.ComponentModel;

namespace ResXImproved
{
	public abstract class ResourceDictionaryConverter<TKey, TValue> : System.ComponentModel.TypeConverter
	{
		protected abstract SortedDictionary<TKey, TValue> CreateDictionaryInstance();

		public override bool CanConvertFrom(ITypeDescriptorContext context, System.Type sourceType)
		{
			Type c = typeof(TKey);
			if (sourceType == typeof(string) && TypeDescriptor.GetConverter(typeof(TKey)).CanConvertFrom(sourceType)
											 && TypeDescriptor.GetConverter(typeof(TValue)).CanConvertFrom(sourceType))
				return true;
			else
				return base.CanConvertFrom(context, sourceType);
		}

		public override bool CanConvertTo(System.ComponentModel.ITypeDescriptorContext context, System.Type destinationType)
		{
			if (destinationType == typeof(string) && TypeDescriptor.GetConverter(typeof(TKey)).CanConvertFrom(destinationType)
											 && TypeDescriptor.GetConverter(typeof(TValue)).CanConvertFrom(destinationType))
				return true;
			else
				return base.CanConvertFrom(context, destinationType);
		}

		public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
		{
			if (value == null) { return new Dictionary<TKey, TValue>(); }

			if (value is String)
			{
				TypeConverter keyConv = TypeDescriptor.GetConverter(typeof(TKey));
				TypeConverter valueConv = TypeDescriptor.GetConverter(typeof(TValue));

				Regex valueRegex = new Regex("\\[([^\\]]*)\\] = \\[([^\\]]*)\\]");
				MatchCollection matches = valueRegex.Matches((string)value);

				SortedDictionary<TKey, TValue> dic = CreateDictionaryInstance();
				foreach (Match m in matches)
				{
					dic[(TKey)keyConv.ConvertFromString(m.Groups[1].Value)] = (TValue)valueConv.ConvertFromString(m.Groups[2].Value);
				}
				return dic;
			}

			return base.ConvertFrom(context, culture, value);
		}

		public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
		{
			if (destinationType == typeof(String))
			{
				StringBuilder sb = new StringBuilder();
				TypeConverter keyConv = TypeDescriptor.GetConverter(typeof(TKey));
				TypeConverter valueConv = TypeDescriptor.GetConverter(typeof(TValue));
				sb.AppendLine();
				foreach (KeyValuePair<TKey, TValue> kv in (SortedDictionary<TKey, TValue>)(value))
				{
					sb.AppendFormat("[{0}] = [{1}]", keyConv.ConvertToString(kv.Key), valueConv.ConvertToString(kv.Value));
					sb.AppendLine();
				}

				return sb.ToString();
			}
			return base.ConvertTo(context, culture, value, destinationType);
		}
	}

	public class StringDictionaryConverter : ResourceDictionaryConverter<string, string>
	{
		protected override SortedDictionary<string, string> CreateDictionaryInstance()
		{
			return new ResourceStringDictionary();
		}
	}

	[TypeConverter(typeof(StringDictionaryConverter)), Serializable()]
	public class ResourceStringDictionary : SortedDictionary<string, string>
	{
	}
}
